home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Sound / MIDI / MIDI Utilities / CMU Midi Toolkit / Source / memstream.c < prev    next >
C/C++ Source or Header  |  1987-01-09  |  8KB  |  269 lines

  1. #include "switches.h"
  2.  
  3. #include "cext.h"
  4. #include "stream.h"
  5. #include "memstream.h"
  6.  
  7. #define READ_ID 28765
  8. #define WRITE_ID 62658
  9.  
  10. typedef struct my_data {
  11.     StreamProcs procs;        /* pointers to generic functions */
  12.     ushort ID;                /* indicates stream type */
  13.     char *buff;                /* start of memory buffer */
  14.     ulong buffSize;            /* size of buffer */
  15.     ulong position;            /* current r/w position in buffer */
  16. } *SelfPtr;
  17.  
  18. void        memstream_close(SelfPtr);
  19. int            memstream_getchar(SelfPtr);
  20. boolean        memstream_getline(SelfPtr, char *, ushort);
  21. ulong        memstream_getpos(SelfPtr);
  22. void        memstream_notImplemented(void);
  23. void        memstream_putchar(SelfPtr, int);
  24. void        memstream_putstring(SelfPtr, char *);
  25. void        memstream_setpos(SelfPtr, ulong);
  26.  
  27.  
  28. /****************************************************************************
  29. *                memstream_OpenRead
  30. * Inputs:
  31. *    char *buff: memory buffer to read from
  32. *    ulong buffSize: size of buff
  33. * Returns:
  34. *    StreamPtr: newly created memory read stream
  35. * Effect:
  36. *    creates a new read stream on the given memory buffer.
  37. *    returns NULL if there is no more memory.
  38. ****************************************************************************/
  39.  
  40. public StreamPtr memstream_OpenRead(buff, buffSize)
  41.     char *buff;
  42.     ulong buffSize;
  43. {
  44.     SelfPtr newStream = (SelfPtr) malloc(sizeof(struct my_data));
  45.  
  46.     if (newStream == NULL) return NULL;
  47.  
  48.     newStream->procs.close = memstream_close;
  49.     newStream->procs.getchr = memstream_getchar;
  50.     newStream->procs.getline = memstream_getline;
  51.     newStream->procs.getpos = memstream_getpos;
  52.     newStream->procs.putchr = memstream_notImplemented;
  53.     newStream->procs.putstring = memstream_notImplemented;
  54.     newStream->procs.setpos = memstream_setpos;
  55.     newStream->ID = READ_ID;
  56.     newStream->buff = buff;
  57.     newStream->buffSize = buffSize;
  58.     newStream->position = 0;
  59.  
  60.     return (StreamPtr) newStream;
  61. }
  62.  
  63. /****************************************************************************
  64. *                memstream_OpenWrite
  65. * Inputs:
  66. *    char *buff: memory buffer to write to
  67. *    ulong buffSize: size of buff
  68. * Returns:
  69. *    StreamPtr: newly created memory write stream
  70. * Effect:
  71. *    creates a new write stream on the given memory buffer.
  72. *    returns NULL if there is no more memory.
  73. ****************************************************************************/
  74.  
  75. public StreamPtr memstream_OpenWrite(buff, buffSize)
  76.     char *buff;
  77.     ulong buffSize;
  78. {
  79.     SelfPtr newStream = (SelfPtr) malloc(sizeof(struct my_data));
  80.  
  81.     if (newStream == NULL) return NULL;
  82.  
  83.     newStream->procs.close = memstream_close;
  84.     newStream->procs.getchr = (int (*)()) memstream_notImplemented;
  85.     newStream->procs.getline = (boolean (*)()) memstream_notImplemented;
  86.     newStream->procs.getpos = memstream_getpos;
  87.     newStream->procs.putchr = memstream_putchar;
  88.     newStream->procs.putstring = memstream_putstring;
  89.     newStream->procs.setpos = memstream_setpos;
  90.     newStream->ID = WRITE_ID;
  91.     newStream->buff = buff;
  92.     newStream->buffSize = buffSize;
  93.     newStream->position = 0;
  94.  
  95.     return (StreamPtr) newStream;
  96. }
  97.  
  98. /****************************************************************************
  99. *                memstream_close
  100. * Inputs:
  101. *    SelfPtr self: a memory stream (read or write)
  102. * Effect:
  103. *    frees the stream data structure.  writes a terminating character to
  104. *    the end of the memory buffer if self is a write stream.
  105. ****************************************************************************/
  106.  
  107. private void memstream_close(self)
  108.     SelfPtr self;
  109. {
  110.     if (self == NULL) return;
  111.     if (self->ID == WRITE_ID) {
  112.         /* Assumes: always room for terminator character */
  113.         self->buff[self->position++] = '\0';
  114.     }
  115.     free((char *) self);
  116. }
  117.  
  118. /****************************************************************************
  119. *                memstream_getchar
  120. * Inputs:
  121. *    SelfPtr self: a memory read stream
  122. * Returns:
  123. *    int: value of character read or -1 (EOF) if at the end of the stream
  124. * Effect:
  125. *    reads a character from the stream
  126. ****************************************************************************/
  127.  
  128. private int memstream_getchar(self)
  129.     SelfPtr self;
  130. {
  131.     if (self->position >= self->buffSize) {
  132.         return EOF;
  133.     } else {
  134.         return (int) self->buff[self->position++];
  135.     }
  136. }
  137.  
  138. /****************************************************************************
  139. *                memstream_getline
  140. * Inputs:
  141. *    SelfPtr self: a memory read stream
  142. *    char * buff: string to read line into
  143. *    ushort buffSize: length of buff
  144. * Returns:
  145. *    boolean: false if we are at the end of the memory stream
  146. * Effect:
  147. *    reads a line of characters from the stream.  a line is terminated by
  148. *    either a newline character or the end of the stream.  if buffSize is less
  149. *    than the length of a given line, only buffSize characters are consumed.
  150. *    (which could potentially cause the client program to think there are
  151. *    line breaks where there aren't; watch out!)
  152. *    NOTE: the terminating newline character is NOT part of the string
  153. *    returned by getline. (thus, the final line in the memory stream looks like
  154. *    any other line regardless of whether the memory buffer ends in a newline.)
  155. ****************************************************************************/
  156.  
  157. private boolean memstream_getline(self, line, lineSize)
  158.     SelfPtr self;
  159.     char *line;
  160.     ushort lineSize;
  161. {
  162.     ulong bytesLeft = self->buffSize - self->position;
  163.     ulong maxBytesToCopy =
  164.         (bytesLeft < (lineSize - 1)) ? bytesLeft : (lineSize - 1);
  165.     register char *srcPtr = self->buff + self->position;
  166.     register char *maxSrcPtr = srcPtr + maxBytesToCopy;
  167.     register char *destPtr = line;
  168.  
  169.     if ((lineSize == 0) || (destPtr == NULL)) return false;
  170.  
  171.     while (srcPtr < maxSrcPtr) {
  172.         if ((*destPtr++ = *srcPtr++) == '\n') {
  173.             destPtr--;    /* don't copy '\n' */
  174.             break;
  175.         }
  176.     }
  177.     *destPtr = '\0';
  178.     self->position = srcPtr - self->buff;
  179.     return ((*line != '\0') || (bytesLeft > 0));
  180. }
  181.  
  182. /****************************************************************************
  183. *                memstream_getpos
  184. * Inputs:
  185. *    SelfPtr self: a memory stream (read or write)
  186. * Returns:
  187. *    ulong: the stream position (i.e. the number of characters from the start)
  188. ****************************************************************************/
  189.  
  190. private ulong memstream_getpos(self)
  191.     SelfPtr self;
  192. {
  193.     return self->position;
  194. }
  195.  
  196. /****************************************************************************
  197. *                memstream_notImplemented
  198. * Effect:
  199. *    prints an error message and exits.  used as a placeholder for functions
  200. *    that make no sense for a particular sort of stream (e.g. getchar for
  201. *    a write stream).
  202. ****************************************************************************/
  203.  
  204. private void memstream_notImplemented()
  205. {
  206.     printf("memstream.c: operation not implemented/n");
  207.     exit(-1);
  208. }
  209.  
  210. /****************************************************************************
  211. *                memstream_putchar
  212. * Inputs:
  213. *    SelfPtr self: a memory write stream
  214. *    int ch: the integer value of the character to write
  215. * Effect:
  216. *    writes ch to the stream
  217. ****************************************************************************/
  218.  
  219. private void memstream_putchar(self, ch)
  220.     SelfPtr self;
  221.     int ch;
  222. {
  223.     if (self->position < (self->buffSize - 1))
  224.         self->buff[self->position++] = (char) ch;
  225. }
  226.  
  227. /****************************************************************************
  228. *                memstream_putstring
  229. * Inputs:
  230. *    SelfPtr self: a memory write stream
  231. *    char * s: the string to put
  232. * Effect:
  233. *    writes the given string to the stream
  234. ****************************************************************************/
  235.  
  236. private void memstream_putstring(self, s)
  237.     SelfPtr self;
  238.     char *s;
  239. {
  240.     ulong bytesLeft = (self->buffSize - self->position) - 2;
  241.         /* save a byte for possible terminator character */
  242.     ushort stringSize = strlen(s);
  243.     ulong maxBytesToCopy = (bytesLeft < stringSize) ? bytesLeft : stringSize;
  244.     register char *srcPtr = s;
  245.     register char *maxSrcPtr = s + maxBytesToCopy;
  246.     register char *destPtr = self->buff + self->position;
  247.  
  248.     while (srcPtr < maxSrcPtr) {
  249.         *destPtr++ = *srcPtr++;
  250.     }
  251.     self->position = destPtr - self->buff;
  252. }
  253.  
  254. /****************************************************************************
  255. *                memstream_setpos
  256. * Inputs:
  257. *    SelfPtr self: a memory stream (read or write)
  258. *    ulong newPos: the new position
  259. * Effect:
  260. *    sets stream position to newPos
  261. ****************************************************************************/
  262.  
  263. private void memstream_setpos(self, newPos)
  264.     SelfPtr self;
  265.     ulong newPos;
  266. {
  267.     self->position = (newPos <= self->buffSize) ? newPos : self->buffSize;
  268. }
  269.